package ga.cross;

import ga.GARun;
import ga.individuals.Individual;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

public class ClassicCross implements CrossMethod {
	private Integer crosspoint;
	
	public ClassicCross() {
		Random r = new Random(System.currentTimeMillis());
		this.crosspoint = r.nextInt(GARun.bitsInDouble);
	}
	
	@Override
	public Collection<Individual> method(Collection<Individual> individuals) {
		/* El cruce se hace entre dos individuos */
		if (individuals.size() != 2) {
			return null;
		}
		List<Individual> listIndividuals = new LinkedList<Individual>(individuals);
		Long firstIndividual = Double.doubleToRawLongBits(listIndividuals.get(0).getIndividualValue());
		Long sndIndividual = Double.doubleToRawLongBits(listIndividuals.get(1).getIndividualValue());
		Long maskSndPart = (0xFFFFFFFFFFFFFFFFL >> this.crosspoint);
		Long maskFirstPart = (0xFFFFFFFFFFFFFFFFL << (GARun.bitsInDouble - this.crosspoint));
		Long firstIndividualFirstPart = firstIndividual & maskFirstPart;
		Long firstIndividualSndPart = firstIndividual & maskSndPart;
		Long sndIndividualFirstPart = sndIndividual & maskFirstPart;
		Long sndIndividualSndPart = sndIndividual & maskSndPart;
		Double newFirstIndividual = Double.longBitsToDouble(firstIndividualFirstPart | sndIndividualSndPart);
		Double newsndIndividual = Double.longBitsToDouble(sndIndividualFirstPart | firstIndividualSndPart);
		Collection<Individual> newIndividuals = new LinkedList<Individual>();
		newIndividuals.add(new Individual(newFirstIndividual));
		newIndividuals.add(new Individual(newsndIndividual));
//		boolean[] bitArrayFirstIndividual = Cross.bytesToBits(Individual.toByteArray(listIndividuals.get(0).getIndividualValue()));
//		boolean[] bitArraySndIndividual = Cross.bytesToBits(Individual.toByteArray(listIndividuals.get(1).getIndividualValue()));
//		boolean aux;
//		
//		for (int i = this.crosspoint; i < Classic.bitsInDouble; i++) {
//			aux = bitArrayFirstIndividual[i];
//			bitArrayFirstIndividual[i] = bitArraySndIndividual[i];
//			bitArraySndIndividual[i] = aux;
//		}
//		
//		Individual newFirstIndividual = new Individual(Individual.toDoubleValue(Cross.bitsToBytes(bitArrayFirstIndividual)));
//		Individual newSndIndividual = new Individual(Individual.toDoubleValue(Cross.bitsToBytes(bitArraySndIndividual)));
//		Collection<Individual> newIndividuals = new LinkedList<Individual>();
//		newIndividuals.add(newFirstIndividual);
//		newIndividuals.add(newSndIndividual);
		
		return newIndividuals;
	}
	
}
